<?php

namespace Biz\module\Classes\mgt;

use Biz\model\trade\Order as mOrder;
use Biz\model\GoodsSku as mGoodsSku;
use Biz\model\trade\OrderRefund as mOrderRefund;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderMatching as mOrderMatching;
use Biz\service\trade\ShopCourier as sShopCourier;
use Biz\module\Classes\core\SearchListAbstract;
use Biz\service\trade\Order as sOrder;
use Biz\tools\Amount;
use Medoo\Medoo;
use Biz\module\Classes\OrderPackage as clsOrderPackage;
use Biz\pockets\constInterface\ActivityInfo;
use Biz\service\activity\PinTuan as sPinTuan;
use Biz\model\trade\OrderPackage as mOrderPackage;

class OrderSearch extends SearchListAbstract
{

    protected $join = []; //关联表
    protected $order = []; //字段排序

    protected $isWaitShip = false;


    protected function buildSelect()
    {
        $this->select = array_merge([
            'o.order_no',
            'o.addtime',
            'o.goods_amount',
            'o.shipping_amount',
            'o.refund_amount',
            'o.message',
            'o.status',
            'o.s_coupon_amount',
            'o.consignee_name',
            'o.consignee_phone',
            'o.consignee_province',
            'o.meal_amount',
            'o.consignee_city',
            'o.consignee_area',
            'o.express_no',
            'o.is_package_delivery',
            'o.pay_time',
            'o.consignee_info_address',
            'o.meal_id',
            'o.activity_allowance',
            'o.coupon_amount',
            'o.order_type',
            'o.delivery_time'
        ],$this->select);
    }

    protected function buildJoin($join)
    {
        $this->join = $join;
    }

    protected function buildOrder($order)
    {
        $this->order = $order;
    }

    protected function buildWhere()
    {
        $this->where['o.shop_id'] = $this->params['shop_id'];

        if (!empty($this->params['status'])) {

            //因为加上了分包裹发货，所以这个地方需要兼容列表
            if($this->params['status'] == mOrder::STATUS_WAIT_SEND){
                $this->params['status'] = [mOrder::STATUS_WAIT_SEND,mOrder::STATUS_SEND_PART_OUT];

                $this->isWaitShip = true;
            }

            $this->where['o.status'] = $this->params['status'];
        }

        if (!empty($this->params['order_no'])) {
            $this->where['o.order_no'] = htmlspecialchars($this->params['order_no']);
        }

        if (!empty($this->params['consignee_phone'])) {
            $this->where['o.consignee_phone'] = htmlspecialchars($this->params['consignee_phone']);
        }

        if (!empty($this->params['consignee_name'])) {
            $this->where['o.consignee_name[~]'] = htmlspecialchars($this->params['consignee_name']);
        }

        if (!empty($this->params['title'])) {
            $this->buildJoin(['[>]order_goods(og)' => ['o.order_no' => 'order_no']]);
            $this->where['og.title[~]'] = htmlspecialchars($this->params['title']);
        }

        if (!empty($this->params['order_type'])) {
            switch ($this->params['order_type']) {
                case 1: //最近下单
                    $this->buildOrder(['ORDER' => ['o.addtime' => 'DESC']]);
                    break;
                case 2: //最早下单
                    $this->buildOrder(['ORDER' => ['o.addtime' => 'ASC']]);
                    break;
                default:
                    break;
            }
        } else {
            $this->buildOrder(['ORDER' => ['o.addtime' => 'DESC']]);
        }


        switch ($this->params['time_type']) {
            case 1: //付款时间
                if (!empty($this->params['start_time'])) {
                    $this->where['o.pay_time[>=]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                }
                if (!empty($this->params['end_time'])) {
                    $this->where['o.pay_time[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']));
                }
                break;
            case 2: //下单时间
                if (!empty($this->params['start_time'])) {
                    $this->where['o.addtime[>=]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                }
                if (!empty($this->params['end_time'])) {
                    $this->where['o.addtime[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']));
                }
                break;
            case 3: //发货时间
                $package_where = [];
                if (!empty($this->params['start_time'])) {
                    $this->where['o.delivery_time[>=]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                    $package_where['delivery_time[>=]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                }
                if (!empty($this->params['end_time'])) {
                    $this->where['o.delivery_time[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']));
                    $package_where['delivery_time[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']));
                }
                if(!empty($package_where)) {
                    if(!empty($this->params['start_time'])){
                        $this->where['OR']['AND']['o.delivery_time[>=]'] = $this->where['o.delivery_time[>=]'] ;
                        unset($this->where['o.delivery_time[>=]']);
                    }
                    if(!empty($this->params['end_time'])){
                        $this->where['OR']['AND']['o.delivery_time[<]'] = $this->where['o.delivery_time[<]'];
                        unset($this->where['o.delivery_time[<]']);
                    }
                    $orderPackage = mOrderPackage::select('order_no', $package_where);
                    if($orderPackage){
                        $this->where['OR']['o.order_no'] =  isset($this->where['o.order_no'])?array_merge($orderPackage, [$this->where['o.order_no']]):$orderPackage;
                    }
                }
                break;
            case 4: //确认收货时间
                if (!empty($this->params['start_time'])) {
                    $this->where['o.confirm_time[>=]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                }
                if (!empty($this->params['end_time'])) {
                    $this->where['o.confirm_time[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']));
                }
                break;
            default:
                break;
        }

        if (!empty($this->params['is_refund'])) {
            if (isset($this->where['o.status'])) {
                if (($this->where['o.status'] != mOrder::STATUS_SUCCESS) && ($this->where['o.status'] != mOrder::STATUS_SEND_OUT) && ($this->where['o.status'] != mOrder::STATUS_WAIT_SEND)) {
                    throw new \Exception('搜索条件只能为交易完成或待发货或待收货的状态才能查看退货退款', 0);
                }
            }
            $this->where['o.refunding_status'] = mOrder::REFUNDING_STATUS_PROCESS;//有退款记录
            //$this->where['o.refund_amount[!]']=0;//有退款成功的
        }


        if($this->isWaitShip){
                $this->select = array_merge($this->select,['om.consignee_time']);

                $this->buildJoin(['[>]order_matching(om)' => ['o.order_no' => 'order_no']]);
                $this->buildOrder(['ORDER'=>['o.addtime'=>'DESC','om.consignee_time'=>'ASC']]);

        }
    }

    public function getCount()
    {
        if ($this->join) {
            $rows = mOrder::get($this->join, ['counts' => Medoo::raw('COUNT(DISTINCT(<o.order_no>))')], $this->where);
            $count = $rows['counts'];
        } else {
            $count = mOrder::count($this->where);
        }
        return $count;
    }

    public function getList()
    {
        if ($this->order) {
            $this->where = $this->where + $this->order;
        }
        if ($this->join) {
            $this->where['GROUP'] = 'o.order_no';
            $this->select['counts'] = Medoo::raw('COUNT(<o.order_no>)'); //方便查看一个符合模糊title订单下的goods-sku的个数
            $orders = mOrder::select($this->join, $this->select, array_merge($this->where, ['LIMIT' => $this->limit]));
        } else {
            if (empty($this->limit)) {
                $orders = mOrder::select($this->select, $this->where);
            } else {
                $orders = mOrder::select($this->select, array_merge($this->where, ['LIMIT' => $this->limit]));
            }
        }

        return $orders;
    }

    public function orderList()
    {

        // 根据条件返回订单号

        $goodsList = [];
        $count = $this->getCount();
        $orders = $this->getList();
        $orderNos = array_column($orders, 'order_no');

        $nowTime = time();

        //发货日期临近提醒
        $shipTip = [];

        if ($orderNos) {
            $orderGoodsList = mOrderGoods::getFieldsByOrderNo($orderNos, '*');

            $skuIds = array_column($orderGoodsList, 'sku_id');

            $skuList = mGoodsSku::getInfoList($skuIds);

            $skuNos = array_column($skuList, 'sku_no', 'id');
            $forcastShipTimes = array_column($skuList,'forecast_ship_time','id');

            $refundList=mOrderRefund::getRefundListByOrderNoForMgtDetailAndList($orderNos);
            $orderRemarks = sOrder::OrderRemarks($orderNos);



            foreach ($orderGoodsList as $key => $orderGoods) {
                $orderGoods['refund_order_no']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['refund_order_no'];
                $orderGoods['rights_process_method']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['rights_process_method'];
                $orderGoods['refund_status']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['status'];
                $orderGoods['refund_status_desc']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['status_desc'];
                $orderGoods['rights_status']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['rights_status'];
                $orderGoods['rights_status_desc']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['rights_status_desc'];
                $orderGoods['type_refund']=$refundList[$orderGoods['order_no']][$orderGoods['sku_id']]['type_refund'];
                $orderGoods['cover_img'] = $orderGoods['cover_img_thumb_url'];
                $orderGoods['sku_no'] = $skuNos[$orderGoods['sku_id']];
                $orderGoods['forcast_ship_time'] = $forcastShipTimes[$orderGoods['sku_id']];


                //商品预期发货时间有效性检测
                if($orderGoods['forcast_ship_time'] > '2010-01-01'){
                    $shipTip[$orderGoods['order_no']][] = $orderGoods['forcast_ship_time'];
                }
                $orderGoods['goods_amount'] = $orderGoods['goods_amount']-$orderGoods['s_coupon_amount']-$orderGoods['meal_amount'];
                $goodsList[$orderGoods['order_no']][] = $orderGoods;

                //是否参与活动
                if( $orderGoods['promo_type'] > 0 ){
                    $activitys[$orderGoods['promo_type']][] = $orderGoods['order_no'];
                }
            }
        }

        if(isset($activitys)){
            $activity = self::getActivity($activitys, $orderGoodsList);
        }

        $orderPackageList = mOrderPackage::getExpressInfoList($orderNos);

        //var_dump(mOrderGoods::sqlLogs());die;
        foreach ($orders as &$orderInfo) {


            if ($orderInfo['consignee_area']) {
                $orderInfo['consignee_code'] = [
                    $orderInfo['consignee_province'],
                    $orderInfo['consignee_city'],
                    $orderInfo['consignee_area']
                ];
            } else {
                $orderInfo['consignee_code'] = [
                    $orderInfo['consignee_province'],
                    $orderInfo['consignee_city']
                ];
            }


            $orderInfo['courier_id']=sShopCourier::getCourierIdByCourierName($orderPackageList[$orderInfo['order_no']][0]['express_company']);

            $orderInfo['status_desc'] = mOrder::$statusMgtDesc[$orderInfo['status']];
            $orderInfo['order_amount'] = Amount::format($orderInfo['goods_amount'] + $orderInfo['shipping_amount']-$orderInfo['s_coupon_amount']-$orderInfo['meal_amount']);
            $orderInfo['goods'] = $goodsList[$orderInfo['order_no']];

            $orderInfo['ship_tip_msg'] = (function () use($orderInfo,$shipTip,$nowTime){
                if(empty($shipTip[$orderInfo['order_no']])){
                    return '';
                }
                foreach ($shipTip[$orderInfo['order_no']] as $time){

                    if(empty($orderInfo['consignee_time'])){
                        continue;
                    }
                    if(!empty($time)){
                        if(strtotime($orderInfo['consignee_time']) >= strtotime($time) && strtotime($time) <= $nowTime){
                            return '请及时发货';
                        }
                    }else{
                        if(strtotime($orderInfo['consignee_time']) <=$nowTime ){
                            return '请及时发货';
                        }
                    }
                }
            })();

			$orderInfo['seller_message'] = $orderRemarks[$orderInfo['order_no']]['seller_message'];
			$orderInfo['hhz_message'] =  isset($orderRemarks[$orderInfo['order_no']]) ? $orderRemarks[$orderInfo['order_no']]['hhz_message'] : [];

			$orderInfo['package_list'] = clsOrderPackage::getOrderPackageList($orderInfo['order_no']);


			if(isset($activity) && !empty($activity)){
                foreach($activity as $_ak=>&$_av) {
                    if (isset($_av[$orderInfo['order_no']])) {
                        $orderInfo[$_ak] = $_av[$orderInfo['order_no']];
                    }
                }
            }
        }

        $allCount = $this->allCount();

        $allCount[0] = mOrder::count(['o.shop_id' => $this->params['shop_id']]); //全部状态

        return ['list' => $orders, 'count' => $count ?: 0, 'all_count' => $allCount];
    }

    private static function getActivity($activity, $skuList){
        $data = [];
        foreach(ActivityInfo::ACTIVITY_TYPES_MAPS as $_k=>$_v) {
            switch ($_k) {
                case ActivityInfo::ACTIVITY_TYPE_PINTUAN;
                    $data = sPinTuan::getSkuOrder($activity[ActivityInfo::ACTIVITY_TYPE_PINTUAN], $skuList);
                    break;
            }
        }
        return $data;
    }

    protected function allCount()
    {
        $counts = [
            mOrder::STATUS_NORMAL    => 0, //待付款
            mOrder::STATUS_WAIT_SEND => 0, //待发货
			mOrder::STATUS_SEND_PART_OUT => 0, //部分发货
            mOrder::STATUS_SEND_OUT  => 0, //待收货
            mOrder::STATUS_SUCCESS   => 0, //交易成功
            mOrder::STATUS_CLOSE     => 0 //交易关闭
        ];
        $allCount = mOrder::select(['counts' => Medoo::raw('COUNT(<o.order_no>)'), 'o.status'], ['GROUP' => 'o.status', 'o.shop_id' => $this->params['shop_id']]);
        array_walk($allCount, function ($v) use (&$counts) {
            if (key_exists($v['status'], $counts)) {
                $counts[$v['status']] = $v['counts'];
            }
        });
        $counts[mOrder::STATUS_WAIT_SEND] = $counts[mOrder::STATUS_WAIT_SEND] + $counts[mOrder::STATUS_SEND_PART_OUT];
        unset($counts[mOrder::STATUS_SEND_PART_OUT]);
        return $counts;
    }

}